// Author: Bjorn Schobben

#include "PropertiesDialog.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QSpacerItem>
#include <QSpinBox>
#include <QColorDialog>
#include <QDialogButtonBox>
#include <QMessageBox>

#include <sstream>
#include <iomanip>

using namespace std;




PropertiesDialog::PropertiesDialog(QWidget *parent): QDialog(parent)
{
	SetupUi();
}

PropertiesDialog::PropertiesDialog(QWidget *parent, const Properties& properties): QDialog(parent), Properties(properties)
{
	SetupUi();
}


PropertiesDialog::~PropertiesDialog()
{
}

// Setup the ui of this dialog
void PropertiesDialog::SetupUi()
{
	QHBoxLayout *hboxLayout;
	QDialogButtonBox *buttonBox;

	setWindowTitle("Properties");
	setModal(true);

    vboxLayout = new QVBoxLayout(this);
    vboxLayout->setSpacing(6);
    vboxLayout->setMargin(9);

	SetupColorSpinBox();
	SetupColorButtons();

    buttonBox = new QDialogButtonBox(this);
    buttonBox->setOrientation(Qt::Horizontal);
    buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok);
	vboxLayout->addWidget(buttonBox);


    QObject::connect(buttonBox, SIGNAL(accepted()), this, SLOT(OnAccepted()));
    QObject::connect(buttonBox, SIGNAL(rejected()), this, SLOT(OnRejected()));

	UpdateButtonStates();
}

void PropertiesDialog::SetupColorSpinBox()
{
	QHBoxLayout *hboxLayout;
    QLabel *label;
    QSpacerItem *spacerItem;
	QSpinBox *spinBox;

	hboxLayout = new QHBoxLayout();
    hboxLayout->setSpacing(6);
    hboxLayout->setMargin(0);
    label = new QLabel(this);
	label->setText("Color count:");
    hboxLayout->addWidget(label);
    spacerItem = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);

    hboxLayout->addItem(spacerItem);

    spinBox = new QSpinBox(this);
    spinBox->setMaximum(MAXCOLOR);
    spinBox->setMinimum(MINCOLOR);
	spinBox->setValue(GetColorCount());
    hboxLayout->addWidget(spinBox);

	vboxLayout->addLayout(hboxLayout);

	QObject::connect(spinBox, SIGNAL(valueChanged(int)), this, SLOT(ColorCountChanged(int)));
}

void PropertiesDialog::SetupColorButtons()
{
	QHBoxLayout *hboxLayout;
    QLabel *label;
    QSpacerItem *spacerItem;
	ColorButton *colorButton;

	for(unsigned int i=0; i<MAXCOLOR; i++)
	{
		hboxLayout = new QHBoxLayout();
		hboxLayout->setSpacing(6);
		hboxLayout->setMargin(0);

		label = new QLabel(this);

		ostringstream s;

		s << "Color " << i+1;
		label->setText(s.str().c_str());

		hboxLayout->addWidget(label);
		spacerItem = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);

		hboxLayout->addItem(spacerItem);

		colorButton = new ColorButton(this);
		colorButton->SetColor(GetColor(i));
		colorButtons[i] = colorButton;

		hboxLayout->addWidget(colorButton);

		vboxLayout->addLayout(hboxLayout);

		QObject::connect(colorButton, SIGNAL(clicked(ColorButton*, Color)), this, SLOT(ColorButtonClicked(ColorButton*, Color)));
	}
}

//Disable color buttons that aren't needed
void PropertiesDialog::UpdateButtonStates()
{
	for(unsigned int i=0; i<MAXCOLOR; i++)
	{
		if (i < GetColorCount())
		{
			colorButtons[i]->setEnabled(true);
		}
		else
		{
			colorButtons[i]->setDisabled(true);
		}
	}
}

//Receives a signal when the user changed the amount of colors to use
void PropertiesDialog::ColorCountChanged(int value)
{
	SetColorCount(value);

	UpdateButtonStates();
}

//Receives a signal when the user clicks a color button
void PropertiesDialog::ColorButtonClicked(ColorButton *button, Color color)
{
	QColor originalColor = QColor( color.GetRed(), color.GetGreen(), color.GetBlue() );
	QColor selectedColor = QColorDialog::getColor(originalColor, this);

	// If the selected color was valid
	if (selectedColor.isValid()) 
	{
		button->SetRed(selectedColor.red());
		button->SetGreen(selectedColor.green());
		button->SetBlue(selectedColor.blue());

		UpdateColors();
	}
}

// Update the internal properties with the new selected colors from the buttons
void PropertiesDialog::UpdateColors()
{
	for(unsigned int i=0; i<MAXCOLOR; i++)
	{
		ColorButton *button = colorButtons[i];
		SetColor( i, Color(button->GetColorValue()) );
	}
}

//emits a signal when the user clicks the OK button, and therefor accepts the properties
void PropertiesDialog::OnAccepted()
{
	// Make sure each color is unique
	if (!IsColorsUnique())
	{
		QMessageBox::critical(this, tr("Properties"), tr("Please give each of the game colors an unique color."));	
	}
	else
	{
		// Notify listeners this dialog was accepted
		emit accepted(*this);

		accept();
	}
}

//Cancel the changes made to the properties
void PropertiesDialog::OnRejected()
{
	reject();
}


